from django.contrib import admin
from django.utils.translation import gettext_lazy, gettext as _
from django.utils.html import format_html
from django.contrib import messages
from django.contrib.admin.filters import SimpleListFilter
from django_object_actions import DjangoObjectActions, action

from utils.model import NoDeleteSelectModelAdmin, BaseModelAdmin
from apps.app_kunyuan.models import KunYuanService
from apps.app_kunyuan.forms import KunYuanServiceForm
from apps.app_kunyuan.managers.kunyuan import KunYuanServiceManager
from apps.app_users.managers import filter_user_queryset


class KunYuanServiceOrgFilter(SimpleListFilter):
    title = gettext_lazy("机构")
    parameter_name = 'org_id'

    def lookups(self, request, model_admin):
        r = KunYuanService.objects.select_related('org_data_center__organization').order_by('sort_weight').values_list(
            'org_data_center__organization_id', 'org_data_center__organization__name'
        )
        d = {i[0]: i[1] for i in r}
        return [(k, v) for k, v in d.items()]

    def queryset(self, request, queryset):
        org_id = request.GET.get(self.parameter_name)
        if org_id:
            return queryset.filter(org_data_center__organization_id=org_id)


@admin.register(KunYuanService)
class KunYuanServiceAdmin(DjangoObjectActions, NoDeleteSelectModelAdmin):
    form = KunYuanServiceForm
    list_display_links = ('id',)
    list_display = ('id', 'name', 'name_en', 'org_data_center', 'organization_name', 'sort_weight',
                    'version', 'version_update_time',
                    'endpoint_url', 'username', 'password', 'raw_password',
                    'creation_time', 'status', 'longitude', 'latitude', 'remarks')
    search_fields = ['name', 'name_en', 'endpoint_url', 'remarks', 'org_data_center__organization__name',
                     'org_data_center__organization__name_en']
    list_filter = [KunYuanServiceOrgFilter, 'status']
    list_select_related = ('org_data_center', 'org_data_center__organization')
    raw_id_fields = ('org_data_center',)
    list_editable = ('sort_weight',)

    readonly_fields = ('password',)
    fieldsets = [
        (gettext_lazy('基础信息'), {'fields': ('org_data_center', 'name', 'name_en', 'endpoint_url', 'status', 'sort_weight',
                                    'longitude', 'latitude', 'remarks')}),
        (gettext_lazy('管理用户和密码'), {'fields': ('username', 'change_password', 'password')}),
        (gettext_lazy('版本号'), {'fields': ('version', 'version_update_time')}),
    ]

    actions = ['update_service_version', 'add_fed_admins_to_select_kunyuans', 'add_admin_to_select_kunyuans']
    change_actions = ('add_admin_to_kunyuan', 'remove_admin_from_kunyuan',
                      'add_fed_admins_to_kunyuan', 'remove_fed_admins_from_kunyuan')

    @admin.action(description=gettext_lazy("添加所有联邦管理员权限到坤元服务"))
    def add_fed_admins_to_select_kunyuans(self, request, queryset):
        usernames = list(filter_user_queryset(is_federal_admin=True).values_list('username', flat=True))
        if not usernames:
            self.message_user(request, _('未配置联邦管理员，未做任何操作。'), level=messages.WARNING)

        for service in queryset:
            self.do_add_fed_admins_to_kunyuan(request=request, service=service, usernames=usernames)

    @action(label=gettext_lazy("添加所有联邦管理员权限到坤元服务"), description=gettext_lazy("添加所有的联邦管理员权限到坤元服务"))
    def add_fed_admins_to_kunyuan(self, request, obj):
        usernames = list(filter_user_queryset(is_federal_admin=True).values_list('username', flat=True))
        if not usernames:
            self.message_user(request, _('未配置联邦管理员，未做任何操作。'), level=messages.WARNING)

        self.do_add_fed_admins_to_kunyuan(request=request, service=obj, usernames=usernames)

    def do_add_fed_admins_to_kunyuan(self, request, service: KunYuanService, usernames: list[str]):
        msg = _('坤元服务为"%(name)s"，用户为%(users)s。') % {
            'name': f'[id={service.id}] {service.name}', 'users': '、'.join(usernames)
        }
        try:
            KunYuanServiceManager.add_admin_to_kunyuan_service(service=service, usernames=usernames)
            self.message_user(request, _('成功添加联邦管理员权限到坤元服务。') + msg, level=messages.SUCCESS)
        except Exception as e:
            self.message_user(request, _('添加联邦管理员权限到坤元服务时错误。') + msg + str(e), level=messages.ERROR)

    @action(label=gettext_lazy("从坤元服务移除所有联邦管理员权限"), description=gettext_lazy("从坤元服务移除所有联邦管理员权限"))
    def remove_fed_admins_from_kunyuan(self, request, obj):
        usernames = list(filter_user_queryset(is_federal_admin=True).values_list('username', flat=True))
        if not usernames:
            self.message_user(request, _('未配置联邦管理员，未做任何操作。'), level=messages.WARNING)

        try:
            KunYuanServiceManager.remove_admin_from_kunyuan_service(service=obj, usernames=usernames)
            self.message_user(request, _('成功从坤元服务移除联邦管理员权限。') + f'users: {usernames}',
                              level=messages.SUCCESS)
        except Exception as e:
            self.message_user(request, _('移除联邦管理员权限时错误。') + str(e), level=messages.ERROR)

    @admin.action(description=gettext_lazy("添加云节点管理员权限到坤元服务"))
    def add_admin_to_select_kunyuans(self, request, queryset):
        for service in queryset:
            self.do_add_admin_to_kunyuan(request=request, service=service)

    @action(label=gettext_lazy("添加云节点管理员权限到坤元服务"), description=gettext_lazy("添加所属的云节点的管理员权限到坤元服务"))
    def add_admin_to_kunyuan(self, request, obj):
        self.do_add_admin_to_kunyuan(request=request, service=obj)

    def do_add_admin_to_kunyuan(self, request, service: KunYuanService):
        service_msg = _('坤元服务为"%(name)s"。') % {'name': f'[id={service.id}] {service.name}'}
        if not service.org_data_center_id:
            self.message_user(request, _('坤元服务单元未关联云节点，无法添加云节点管理员权限到坤元服务。') + service_msg,
                              level=messages.WARNING)
            return

        usernames = KunYuanServiceManager.get_odc_admin_usernames(odc_id=service.org_data_center_id)
        if not usernames:
            self.message_user(request, _('坤元服务单元关联的云节点未配置管理员，未做任何操作。') + service_msg,
                              level=messages.WARNING)

        msg = service_msg + _('用户为%(users)s。') % {'users': '、'.join(usernames)}
        try:
            KunYuanServiceManager.add_admin_to_kunyuan_service(service=service, usernames=usernames)
            self.message_user(request, _('成功添加云节点管理员权限到坤元服务。') + msg, level=messages.SUCCESS)
        except Exception as e:
            self.message_user(request, _('添加云节点管理员权限到坤元服务时错误。') + msg + str(e), level=messages.ERROR)

    @action(label=gettext_lazy("从坤元服务移除云节点管理员权限"), description=gettext_lazy("从坤元服务移除所属的云节点的管理员权限"))
    def remove_admin_from_kunyuan(self, request, obj):
        if not obj.org_data_center_id:
            self.message_user(request, _('坤元服务单元未关联云节点，无法移除云节点管理员权限。'),
                              level=messages.WARNING)
            return

        usernames = KunYuanServiceManager.get_odc_admin_usernames(odc_id=obj.org_data_center_id)
        if not usernames:
            self.message_user(request, _('坤元服务单元关联的云节点未配置管理员，未做任何操作。'), level=messages.WARNING)

        try:
            KunYuanServiceManager.remove_admin_from_kunyuan_service(service=obj, usernames=usernames)
            self.message_user(request, _('成功从坤元服务移除云节点管理员权限。') + f'users: {usernames}',
                              level=messages.SUCCESS)
        except Exception as e:
            self.message_user(request, _('从坤元服务移除云节点管理员权限时错误。') + str(e), level=messages.ERROR)

    @admin.action(description=gettext_lazy("更新服务版本信息"))
    def update_service_version(self, request, queryset):
        count = 0
        for service in queryset:
            if service.status != KunYuanService.Status.ENABLE.value:
                continue

            ok = KunYuanServiceManager.update_service_version(service=service)
            if ok is True:
                count += 1

        if count > 0:
            self.message_user(request, _("更新版本数量:") + str(count), level=messages.SUCCESS)
        else:
            self.message_user(request, _("没有更新任何服务单元版本"), level=messages.SUCCESS)

    @admin.display(description=gettext_lazy("机构"))
    def organization_name(self, obj):
        if not obj.org_data_center or not obj.org_data_center.organization:
            return ''

        return obj.org_data_center.organization.name

    @admin.display(description=gettext_lazy("原始密码"))
    def raw_password(self, obj):
        passwd = obj.raw_password()
        if not passwd:
            return passwd

        return format_html(f'<div title="{passwd}">******</div>')
